package 二叉树;

public class No235二叉搜索树的最近公共祖先 {

    /**
     * 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
     *
     * 百度百科中最近公共祖先的定义为：“对于有根树 T 的两个结点 p、q，
     * 最近公共祖先表示为一个结点 x，满足 x 是 p、q 的祖先且 x 的深度尽可能大（一个节点也可以是它自己的祖先）。”
     *
     * 示例 1:
     *
     * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
     * 输出: 6
     * 解释: 节点 2 和节点 8 的最近公共祖先是 6。
     *
     * 示例 2:
     *
     * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
     * 输出: 2
     * 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
     */

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        int rootNum=root.val;
        if(root==p||root==q)
            return root;//有一个相等,那么公共就在中间
        if(p.val<=rootNum&&q.val>=rootNum)
            return root;//在两侧,则公共就在中间
        //左子树有一个孩子,并且右子树也有一个孩子,则此节点是公共祖先
        TreeNode maxNode=p.val>=q.val?p:q;
        TreeNode minNode=maxNode==p?q:p;
        return op(root, minNode, maxNode);
    }

    //找到那颗中间节点,min小于node,max大于node
    private TreeNode op(TreeNode node,TreeNode minNode,TreeNode maxNode){
        if(node==null)
            return null;
        if(node.val<=maxNode.val&&node.val>=minNode.val)
            return node;
        if(maxNode.val<node.val)
            return op(node.left,minNode,maxNode);
        return op(node.right,minNode,maxNode);
    }

}
